package cn.yogehaoren.agile_gateway.util;

import cn.yogehaoren.agile_gateway.entity.ServiceAddress;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.Watcher;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author WangNing
 * @since 1.0
 */
@Slf4j
public class ServiceWatcher implements Watcher<Service> {


    private final ReentrantReadWriteLock.WriteLock writeLock ;

    private final Map<String, ServiceAddress> serviceAddressMap;

    private final String routeId;

    private final String serviceName;

    private final String scheme;

    private final Integer port;
    public ServiceWatcher(ReentrantReadWriteLock.WriteLock writeLock, Map<String, ServiceAddress> serviceAddressMap,
                          String routeId, String serviceName, String scheme, Integer port
                          ){

        this.writeLock = writeLock;
        this.serviceAddressMap = serviceAddressMap;
        this.routeId = routeId;
        this.serviceName =serviceName;

        this.scheme = scheme;
        this.port = port;



    }

    @Override
    public void eventReceived(Action action, Service resource) {

            // 放置监听器当service改变时， 清除service缓存

            if(resource.getMetadata().getName().equals(serviceName)){
                switch (action){

                    case DELETED: case MODIFIED: case ERROR:{
                        try{
                            this.writeLock.lock();
                            log.trace("--> {} 发生变更, 淘汰缓存", serviceName);
                        }finally {
                            log.trace("<-- {} 缓存淘汰完成", serviceName);
                            this.writeLock.unlock();
                        }
                        this.serviceAddressMap.remove(routeId);
                        break;
                    }
                    case ADDED:
                    {
                        try {
                            log.trace("--> 新建 {} 生成缓存", serviceName);
                            ServiceAddress serviceAddress = ServiceAddress.builder()
                                    .scheme(scheme).host(resource.getSpec().getClusterIP()).port(port).build();
                            this.serviceAddressMap.put(routeId, serviceAddress);
                            this.writeLock.lock();
                        }finally {
                            log.trace("<-- 新建 {} 缓存完成", serviceName);
                            this.writeLock.unlock();
                        }
                    }


                }
            }



    }

    @Override
    public void onClose(KubernetesClientException cause) {

    }
}
